/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controllers;

import Algorithms.Comparaciones;
import Models.TwitterFriend;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import validadorxml.ValidadorXML;

/**
 *
 * Controla las funciones que se realizan en el Archivo XML de Twitter.
 * @author Daniel Ochoa John
 */
public class TwitterController {
    
    public String RUTA_SCHEMA = "xsd/TwitterFriendSchema.xsd";
    String RUTA_TWITTER;
    String RUTA_ABSOLUTA;
    private ArrayList<TwitterFriend> TFriends = new ArrayList();
    float[][] track; 
    ArrayList ocupados = new ArrayList();
    private ArrayList<TwitterFriend> TFriendsM = new ArrayList();
    
    
    
    
    /**
     * 
     * Constructor de la clase TwitterController
     * 
     * @param Ruta Ruta física del archivo XML que contiene los datos de Twitter.
     */
    public TwitterController(String Ruta)
    {
        this.RUTA_TWITTER = Ruta;
        File f = new File(RUTA_SCHEMA);
        RUTA_ABSOLUTA = f.getAbsolutePath();
        f = null;
    }
    
    
    /**
     * 
     * Valida el archivo XML de Twitter contra su respectivo Schema
     * 
     * @return Retorna verdadero si el archivo es válido.<br> Falso si no es válido.
     */
    public boolean ValidarArchivo()
    {
        ValidadorXML validador = new ValidadorXML();
        validador.validarXMLconXSD(RUTA_ABSOLUTA, RUTA_TWITTER, false);
        return validador.es_valido();
    }
    
    
    /**
     * 
     * Lee el archivo XML que contiene los datos de Twitter, almacenando la información en un arreglo.
     * 
     * @return Retorna verdadero si la lectura fue exitosa.<br> Falso si la lectura no ha sido posible.
     */
    public boolean LeerArchivo()
    {
        try
        {
            SAXBuilder  builder = new SAXBuilder();
            File TwitterXMLFile = new File(this.RUTA_TWITTER);           
            org.jdom.Document document = (org.jdom.Document)builder.build(TwitterXMLFile);
            org.jdom.Element RootNode = document.getRootElement();
            List list = RootNode.getChildren("friend");
            for(int i=0;i<list.size();i++)
            {
                org.jdom.Element node = (org.jdom.Element) list.get(i);
                try
                {
                        TwitterFriend TF = new TwitterFriend
                        (
                            node.getChildText("user_name"),
                            Long.valueOf(node.getChildText("twitter_id")),
                            node.getChildText("twitter_name"),
                            node.getChildText("profile_image_url"),
                            node.getChildText("user_description"),
                            Integer.valueOf(node.getChildText("num_mentions"))
                        );
                        this.TFriends.add(TF);
                }
                catch(Exception ex)
                {
                    return false;
                }
            }
        }
        catch (JDOMException ex) {
            return false;
        } catch (IOException ex) {
            return false;
        }
        
        return true;
    }
    
    
    
    /**
     * 
     * Analiza si es que en los datos de Twitter existen dos contactos iguales.<br> En otras palabras, analiza si
     * una misma persona tiene dos perfiles distintos.
     * 
     */
    public void AnalizaDuplicados()
    {
        track = new float[TFriends.size()][TFriends.size()];
        for(int i = 0; i<TFriends.size(); i++)
        {
            TwitterFriend aux = this.TFriends.get(i);
            
            for(int j = 0; j<TFriends.size();j++)
            {
                TwitterFriend aux2 = this.TFriends.get(j);
                
                if(i!=j)
                {
                    if((track[i][j]== 0)&&(track[j][i]==0))
                    {    
                        float resultado = (Comparaciones.CompararNombres(aux.getNombre(), aux2.getNombre()));
                        if(resultado == 0)
                        {
                            track[i][j] = -1;
                            track[j][i] = -1;
                        }
                        else
                        {
                            track[i][j] = (Comparaciones.CompararNombres(aux.getNombre(), aux2.getNombre()));
                            track[j][i] = (Comparaciones.CompararNombres(aux.getNombre(), aux2.getNombre()));
                        }
                        
                        if(resultado >= 0.8)
                        {
                            ocupados.add(i);
                            ocupados.add(j);
                            this.TFriendsM.add(UnirDuplicados(aux,aux2));
                        }
                        
                    }
                }
            }
            
            if(!(this.ocupados.contains(i)))
            {
                this.TFriendsM.add(TFriends.get(i));
            }
            
        }
        
    }
    
   /**
     * 
     * Une dos amigos de Twitter en uno solo.<br>Este método se utiliza para unir amigos si es que se detecta algún duplicado.
     * 
     * @param A Amigo de Twitter 1
     * @param B Amigo de Twitter 2
     * @return Un amigo de Twitter con la información unida desde A y B.
     */
    private TwitterFriend UnirDuplicados(TwitterFriend A,TwitterFriend B)
    {
        
        int NumMentions = A.getNumMentions() + B.getNumMentions();
        String Nombre;
        String TwitterName;
        String URL;
        String Descripcion;
        Long ID;
        
        
        if(A.getNombre().length() >= B.getNombre().length())
        {
            Nombre = A.getNombre();
        }
        else
        {
            Nombre = B.getNombre();
        }
        
        
        if(A.getID()>B.getID())
        {
            TwitterName = A.getTwitterName();
            URL = A.getURL();
            Descripcion = A.getDescripcion();
            ID = A.getID();
        }
        else
        {
            TwitterName = B.getTwitterName();
            URL = B.getURL();
            Descripcion = B.getDescripcion();
            ID = B.getID();
        }
        
        TwitterFriend Merged = new TwitterFriend(
                Nombre,
                ID,
                TwitterName,
                URL,
                Descripcion,
                NumMentions
                );
        
        return Merged;
        
    }
    
    /**
     * 
     * Retorna la lista completa de amigos de Twitter ya sin contactos duplicados.
     * 
     * @return Una lista de objetos TwitterFriend, que representa a todos los amigos de Twitter del usuario.
     */
    public ArrayList<TwitterFriend> getTFriendsM() {
        return TFriendsM;
    }

    public void setRUTA_SCHEMA(String RUTA_SCHEMA) {
        this.RUTA_SCHEMA = RUTA_SCHEMA;
    }
    
    
}
